import { getFullImageUrl } from '../../utils/request';
import BackButton from '../../components/common/BackButton.vue';
import CryptoJS from '../../utils/crypto-js';

export default {
  components: {
    BackButton
  },
  data() {
      return {
        isRecording: false,
        isConnecting: false,
        isConnected: false,
        isClosing: false,
        recognitionResult: '',
        recognitionResultTemp: '', // 用于存储临时识别结果，支持动态修正
        recorderManager: null,
        webSocketTask: null,
        tempFilePath: '',
        timer: null,
        heartbeatInterval: null,
        statusText: '准备就绪',
        // 讯飞语音听写配置
        appId: '4d46ab89', // 讯飞API的AppID
        apiKey: '206033a67258e071c1f8901dcbd7aad8', // 讯飞API的API Key
        apiSecret: 'MDJiODdhOTBmMWM2Y2ZiMzRjYWY0M2Y4', // 讯飞API的API Secret
        // 录音配置
        recordOptions: {
          format: 'pcm',
          sampleRate: 16000,
          numberOfChannels: 1,
          encodeBitRate: 96000,
          frameSize: 1280
        }
      };
    },
  onLoad(options) {
    // 如果从其他页面传入了参数，可以在这里接收
    if (options.appid) this.appId = options.appid;
    if (options.apiKey) this.apiKey = options.apiKey;
    if (options.apiSecret) this.apiSecret = options.apiSecret;
    
    this.initRecorderManager();
  },
  onUnload() {
      // 清理资源
      this.stopRecording();
      this.closeWebSocket();
      clearTimeout(this.timer);
      this.stopHeartbeat();
    },
  methods: {
    getFullImageUrl(url) {
      return getFullImageUrl(url);
    },
    // 返回上一页
    goBack() {
      uni.navigateBack();
    },
    
    // 初始化录音管理器 - 微信小程序增强版本
    initRecorderManager() {
      try {
        // 检查微信小程序环境
        console.log('检查运行环境:', typeof wx);
        
        // 在微信小程序中，优先使用wx.getRecorderManager
        if (typeof wx !== 'undefined' && wx.getRecorderManager) {
          this.recorderManager = wx.getRecorderManager();
          console.log('使用微信小程序原生录音管理器');
        } else {
          // 使用uni-app的录音管理器
          this.recorderManager = uni.getRecorderManager();
          console.log('使用uni-app录音管理器');
        }
        
        console.log('录音管理器初始化成功');
        
        // 监听录音开始事件
        this.recorderManager.onStart(() => {
          console.log('开始录音');
          this.isRecording = true;
          this.statusText = '录音中...';
          // 设置录音时长限制，最长60秒
          this.timer = setTimeout(() => {
            this.stopRecording();
            uni.showToast({
              title: '录音时长已达上限',
              icon: 'none'
            });
          }, 60000);
          
          // 清除之前的识别结果
          this.clearResult();
          
          // 记录录音开始时间，用于限制录音时长
          this.recordingStartTime = Date.now();
        });
        
        // 监听录音暂停事件
        if (this.recorderManager.onPause) {
          this.recorderManager.onPause(() => {
            console.log('录音暂停');
            this.statusText = '录音已暂停';
          });
        }
        
        // 监听录音停止事件
        this.recorderManager.onStop((res) => {
          console.log('录音停止', res);
          this.isRecording = false;
          clearTimeout(this.timer);
          
          // 检查录音文件是否存在
          if (!res.tempFilePath) {
            console.error('录音文件路径不存在', res);
            this.statusText = '录音文件生成失败';
            uni.showToast({
              title: '录音文件生成失败',
              icon: 'none'
            });
            return;
          }
          
          this.tempFilePath = res.tempFilePath;
          this.statusText = '正在建立WebSocket连接...';
          
          // 检查录音时长，防止空文件
          if (res.duration && res.duration < 0.5) {
            console.warn('录音时长过短:', res.duration);
            this.statusText = '录音时长过短';
            uni.showToast({
              title: '录音时长过短，请重新录音',
              icon: 'none'
            });
            return;
          }
          
          // 录音停止后自动进行语音识别
          this.initiateVoiceRecognition();
        });
        
        // 监听录音错误事件
        this.recorderManager.onError((err) => {
          console.error('录音错误', err);
          this.isRecording = false;
          clearTimeout(this.timer);
          this.statusText = '录音失败';
          
          // 在微信小程序中提供更详细的错误提示
          let errorMsg = '录音失败';
          if (err.errCode === 10001) {
            errorMsg = '没有录音权限，请授权后重试';
          } else if (err.errCode === 10002) {
            errorMsg = '录音设备异常';
          } else if (err.errCode === 10003) {
            errorMsg = '录音文件保存失败';
          } else if (err.errCode === 10004) {
            errorMsg = '录音时长超过限制';
          } else if (err.errMsg) {
            errorMsg = '录音失败: ' + err.errMsg;
          }
          
          // 显示错误提示
          uni.showToast({
            title: errorMsg,
            icon: 'none'
          });
        });
        
        // 监听录音实时数据，用于调试
        if (this.recorderManager.onFrameRecorded) {
          this.recorderManager.onFrameRecorded((res) => {
            const { frameBuffer } = res;
            console.log(`接收到录音帧，大小: ${frameBuffer.byteLength}字节`);
            // 可以在这里添加音频质量检测逻辑
          });
        }
        
        // 配置录音参数
        this.recorderConfig = {
          duration: 60000, // 最长录音时长1分钟
          sampleRate: 16000, // 采样率，与讯飞API要求一致
          numberOfChannels: 1, // 单声道
          encodeBitRate: 96000, // 编码码率
          format: 'pcm', // 格式，与原始代码保持一致
          frameSize: 1280 // 与原始代码保持一致
        };
        
        console.log('录音配置:', this.recorderConfig);
      } catch (error) {
        console.error('初始化录音管理器失败', error);
        this.statusText = '初始化录音管理器失败';
        
        // 显示更友好的错误提示
        uni.showToast({
          title: '初始化录音功能失败',
          icon: 'none'
        });
        
        throw error;
      }
    },
    
    // 切换语音输入状态
    async toggleVoiceInput() {
      if (this.isRecording) {
        // 停止录音
        this.stopRecording();
      } else {
        // 开始录音
        await this.startRecording();
      }
    },
    
    // 开始录音 - 微信小程序增强版本
    async startRecording() {
      try {
        // 检查是否已经在录音
        if (this.isRecording) {
          console.warn('正在录音中，无需重复开始');
          return;
        }
        
        // 检查录音管理器是否初始化
        if (!this.recorderManager) {
          console.error('录音管理器未初始化');
          this.initRecorderManager();
        }
        
        // 显示录音准备提示
        uni.showToast({
          title: '请开始说话...',
          icon: 'none',
          duration: 1000
        });
        
        // 检查录音权限
        const { authSetting } = await uni.getSetting();
        if (!authSetting['scope.record']) {
          const { confirm } = await uni.showModal({
            title: '权限请求',
            content: '需要您的录音权限以进行语音识别',
            showCancel: true
          });
          if (!confirm) {
            uni.showToast({
              title: '请授予录音权限',
              icon: 'none'
            });
            return;
          }
          
          // 请求录音权限
          try {
            await uni.authorize({
              scope: 'scope.record'
            });
          } catch (authError) {
            // 用户拒绝授权，引导用户去设置页面
            uni.showModal({
              title: '需要录音权限',
              content: '请在设置中允许应用访问您的麦克风以使用语音输入功能',
              showCancel: true,
              confirmText: '去设置',
              cancelText: '取消',
              success: (res) => {
                if (res.confirm) {
                  // 打开设置页面
                  if (typeof wx !== 'undefined' && wx.openSetting) {
                    wx.openSetting({
                      success: (res) => {
                        console.log('用户打开设置页面', res);
                      }
                    });
                  } else {
                    uni.openSetting();
                  }
                }
              }
            });
            return;
          }
        }
        
        // 开始录音，使用预设的配置
        this.recorderManager.start(this.recorderConfig || this.recordOptions);
        
        // 添加超时处理，防止录音时间过长
        this.recordingTimeout = setTimeout(() => {
          if (this.isRecording) {
            console.log('录音超时，自动停止');
            this.stopRecording();
            uni.showToast({
              title: '录音已达最大时长',
              icon: 'none'
            });
          }
        }, 60000); // 60秒超时
        
        uni.showToast({
          title: '录音中...',
          icon: 'none'
        });
      } catch (error) {
        console.error('开始录音失败', error);
        this.statusText = '请授予录音权限';
        
        // 在微信小程序中提供更详细的错误提示
        let errorMsg = '请授予录音权限';
        if (error.errMsg && error.errMsg.includes('auth deny')) {
          errorMsg = '没有录音权限，请授权后重试';
        } else if (error.message) {
          errorMsg = error.message;
        }
        
        uni.showToast({
          title: errorMsg,
          icon: 'none'
        });
      }
    },
    
    // 停止录音
    stopRecording() {
      if (this.recorderManager && this.isRecording) {
        this.recorderManager.stop();
      }
    },
    
    // 初始化语音识别过程 - 微信小程序增强版本
    async initiateVoiceRecognition() {
      try {
        // 检查网络状态
        const networkStatus = await new Promise((resolve, reject) => {
          uni.getNetworkType({
            success: (res) => resolve(res.networkType),
            fail: (err) => reject(err)
          });
        });
        
        if (networkStatus === 'none') {
          throw new Error('无网络连接');
        }
        
        console.log('网络状态正常，类型:', networkStatus);
        
        // 清除之前的识别结果
        this.recognitionResult = "";
        this.recognitionResultTemp = "";
        
        // 检查录音文件是否存在
        if (!this.tempFilePath) {
          throw new Error('录音文件路径不存在');
        }
        
        console.log('准备开始识别，录音文件:', this.tempFilePath);
        
        // 检查微信小程序环境下的文件访问权限
        try {
          const fs = uni.getFileSystemManager();
          // 尝试获取文件信息，验证文件是否可访问
          const fileInfo = await new Promise((resolve, reject) => {
            fs.getFileInfo({
              filePath: this.tempFilePath,
              success: resolve,
              fail: reject
            });
          });
          
          console.log('录音文件信息:', fileInfo);
          
          // 检查文件大小是否合理
          if (fileInfo.size < 1024) {
            console.warn('录音文件过小，可能导致识别失败');
            uni.showToast({
              title: '录音质量不佳，可能影响识别效果',
              icon: 'none'
            });
          }
        } catch (fileError) {
          console.error('检查录音文件失败:', fileError);
          throw new Error('录音文件异常，请重新录音');
        }
        
        // 先建立WebSocket连接
        this.isConnecting = true;
        await this.createWebSocketConnection();
        // 连接成功后发送音频数据
        await this.sendAudioData();
      } catch (error) {
        console.error('语音识别过程失败', error);
        this.statusText = '识别失败';
        
        // 在微信小程序中提供更详细的错误提示
        let errorMsg = '识别失败';
        if (error.message.includes('网络')) {
          errorMsg = '网络连接异常，请检查网络';
        } else if (error.message.includes('WebSocket')) {
          errorMsg = '连接语音识别服务器失败';
        } else if (error.message.includes('录音文件')) {
          errorMsg = '录音文件异常，请重新录音';
        } else if (error.message.includes('超时')) {
          errorMsg = '连接超时，请检查网络或重试';
        } else {
          errorMsg = '识别失败: ' + error.message;
        }
        
        uni.showToast({
          title: errorMsg,
          icon: 'none',
          duration: 3000
        });
        this.closeWebSocket();
      }
    },

    // 创建WebSocket连接 - 增强连接稳定性
    async createWebSocketConnection() {
      const maxRetries = 2; // 最大重试次数
      let retries = 0;
      
      // 内部连接函数，支持重试
      const connectWithRetry = () => {
        return new Promise((resolve, reject) => {
          try {
            // 检查网络状态
            uni.getNetworkType({
              success: (res) => {
                if (res.networkType === 'none') {
                  reject(new Error('网络不可用，请检查网络连接'));
                  return;
                }
                
                // 生成WebSocket连接地址
                const wsUrl = this.generateWebSocketUrl();
                console.log('WebSocket连接地址:', wsUrl);
                
                // 创建WebSocket连接 - 使用推荐的iat-api.xfyun.cn域名
                this.webSocketTask = uni.connectSocket({
                  url: wsUrl,
                  // 增加连接参数以优化流式体验
                  protocols: ['protocol1'],
                  success: () => {
                    console.log('WebSocket连接成功创建');
                    
                    // 监听WebSocket连接打开
                    if (this.webSocketTask) {
                      this.webSocketTask.onOpen(() => {
                        console.log('WebSocket连接已打开');
                        this.isConnecting = false;
                        this.isConnected = true;
                        this.statusText = 'WebSocket连接已建立，正在发送音频数据...';
                        
                        // 启动心跳包机制，保持连接活跃
                        this.startHeartbeat();
                        
                        resolve();
                      });
                      
                      // 监听WebSocket接收到消息
                      this.webSocketTask.onMessage((res) => {
                        console.log('接收到WebSocket消息:', res);
                        this.handleWebSocketMessage(res.data);
                      });
                      
                      // 监听WebSocket错误
                      this.webSocketTask.onError((err) => {
                        console.error('WebSocket错误', err);
                        this.isConnecting = false;
                        this.isConnected = false;
                        this.statusText = 'WebSocket连接错误';
                        
                        // 提供更详细的错误信息
                        const errorMsg = err.errMsg || '未完成的操作';
                        const detailedError = 'WebSocket错误: ' + errorMsg;
                        console.error(detailedError);
                        
                        // 如果是临时错误且未达到最大重试次数，则尝试重试
                        if (detailedError.includes('timeout') && retries < maxRetries) {
                          retries++;
                          console.log(`WebSocket连接失败，尝试重试(${retries}/${maxRetries})...`);
                          // 清理资源
                          this.cleanupWebSocket();
                          // 延迟重试，避免频繁重试
                          setTimeout(() => {
                            connectWithRetry().then(resolve).catch(reject);
                          }, 1000 * retries); // 递增延迟
                        } else {
                          // 达到最大重试次数或非临时错误，直接拒绝
                          reject(new Error(detailedError));
                        }
                      });
                      
                      // 监听WebSocket关闭
                      this.webSocketTask.onClose((res) => {
                        console.log('WebSocket连接已关闭', res);
                        this.isConnecting = false;
                        this.isConnected = false;
                        this.statusText = 'WebSocket连接已关闭';
                        
                        // 停止心跳
                        this.stopHeartbeat();
                      });
                    }
                  },
                  fail: (err) => {
                    console.error('WebSocket连接创建失败', err);
                    
                    // 如果是临时错误且未达到最大重试次数，则尝试重试
                    if (err.errMsg && err.errMsg.includes('timeout') && retries < maxRetries) {
                      retries++;
                      console.log(`WebSocket连接失败，尝试重试(${retries}/${maxRetries})...`);
                      // 延迟重试，避免频繁重试
                      setTimeout(() => {
                        connectWithRetry().then(resolve).catch(reject);
                      }, 1000 * retries); // 递增延迟
                    } else {
                      reject(new Error('WebSocket连接创建失败: ' + err.errMsg));
                    }
                  }
                });
              },
              fail: (err) => {
                console.error('获取网络状态失败', err);
                reject(new Error('无法获取网络状态'));
              }
            });
            
            // 设置连接超时
            setTimeout(() => {
              if (this.isConnecting) {
                // 如果是临时错误且未达到最大重试次数，则尝试重试
                if (retries < maxRetries) {
                  retries++;
                  console.log(`WebSocket连接超时，尝试重试(${retries}/${maxRetries})...`);
                  // 清理资源
                  this.cleanupWebSocket();
                  // 延迟重试
                  setTimeout(() => {
                    connectWithRetry().then(resolve).catch(reject);
                  }, 1000 * retries);
                } else {
                  reject(new Error('WebSocket连接超时，请检查网络连接或重试'));
                  
                  // 清理资源
                  this.cleanupWebSocket();
                  
                  // 更新状态
                  this.isConnecting = false;
                  this.isConnected = false;
                  this.statusText = 'WebSocket连接超时';
                }
              }
            }, 10000); // 10秒超时时间
          } catch (error) {
            console.error('创建WebSocket连接异常', error);
            reject(error);
          }
        });
      };
      
      return connectWithRetry();
    },
    
    // 启动心跳包机制
    startHeartbeat() {
      // 清除之前的心跳定时器
      this.stopHeartbeat();
      
      // 每30秒发送一次心跳包
      this.heartbeatInterval = setInterval(() => {
        if (this.isConnected && this.webSocketTask) {
          try {
            // 发送心跳包，保持连接活跃
            const heartbeatMsg = JSON.stringify({type: 'heartbeat'});
            this.webSocketTask.send({
              data: heartbeatMsg,
              fail: (err) => {
                console.error('发送心跳包失败', err);
                // 心跳失败可能表示连接已断开
              }
            });
          } catch (error) {
            console.error('发送心跳包异常', error);
          }
        }
      }, 30000);
    },
    
    // 停止心跳包
    stopHeartbeat() {
      if (this.heartbeatInterval) {
        clearInterval(this.heartbeatInterval);
        this.heartbeatInterval = null;
      }
    },
    
    // 清理WebSocket资源
    cleanupWebSocket() {
      try {
        // 先更新状态标志
        this.isConnecting = false;
        
        // 只有当webSocketTask存在且isClosing为false时才尝试关闭
        if (this.webSocketTask && !this.isClosing) {
          // 使用abort方法来终止连接创建过程（微信小程序特有的方法）
          if (this.webSocketTask.abort && typeof this.webSocketTask.abort === 'function') {
            console.log('使用abort方法中止WebSocket连接过程');
            this.webSocketTask.abort();
          } else {
            // 对于不支持abort的环境，尝试使用close并捕获可能的错误
            try {
              // 直接使用close方法关闭
              if (typeof this.webSocketTask.close === 'function') {
                try {
                  this.webSocketTask.close({code: 1000});
                } catch (e) {
                  this.webSocketTask.close();
                }
              }
            } catch (closeError) {
              console.warn('尝试关闭WebSocket连接失败:', closeError);
            }
          }
          
          // 延迟设置为null，给底层一点时间处理关闭事件
          setTimeout(() => {
            if (this.webSocketTask) {
              console.log('清理webSocketTask引用');
              this.webSocketTask = null;
            }
          }, 200);
        }
      } catch (abortError) {
        console.warn('中止WebSocket连接过程时出错:', abortError);
        // 无论如何都要设置为null，防止内存泄漏
        setTimeout(() => {
          this.webSocketTask = null;
        }, 200);
      }
    },
    
    // 生成WebSocket连接地址 - 添加详细日志和错误处理
    generateWebSocketUrl() {
      try {
        // 生成RFC1123格式的时间戳
        const date = new Date();
        const dateStr = date.toUTCString();
        
        // 使用讯飞API文档推荐的域名
        const host = 'iat-api.xfyun.cn';
        
        // 构建签名原文
        const signatureOrigin = `host: ${host}\ndate: ${dateStr}\nGET /v2/iat HTTP/1.1`;
        
        console.log('生成签名原文:', signatureOrigin);
        
        // 使用HmacSHA256计算签名
        const hash = CryptoJS.HmacSHA256(signatureOrigin, this.apiSecret);
        
        // 对签名进行Base64编码
        const signatureBase64 = CryptoJS.enc.Base64.stringify(hash);
        
        console.log('签名Base64:', signatureBase64);
        
        // 构建认证字符串
        const authorization = `api_key="${this.apiKey}", algorithm="hmac-sha256", headers="host date request-line", signature="${signatureBase64}"`;
        
        // 对认证字符串进行URL编码
        const authorizationEncoded = encodeURIComponent(authorization);
        
        // 构建WebSocket连接地址
        const wsUrl = `wss://${host}/v2/iat?authorization=${authorizationEncoded}&date=${encodeURIComponent(dateStr)}&host=${host}`;
        
        console.log('生成的WebSocket URL:', wsUrl);
        
        return wsUrl;
      } catch (error) {
        console.error('生成WebSocket连接地址失败', error);
        // 在微信小程序中，可能需要检查CryptoJS的实现是否兼容
        console.error('当前使用的CryptoJS:', JSON.stringify(CryptoJS, null, 2));
        throw new Error('生成WebSocket连接地址失败: ' + error.message);
      }
    },
    
    // 发送音频数据 - 微信小程序增强兼容性版本
    async sendAudioData() {
      try {
        if (!this.isConnected || !this.webSocketTask) {
          throw new Error('WebSocket未连接');
        }
        
        // 读取录音文件
        const fileData = await this.readFile(this.tempFilePath);
        console.log('读取到的文件数据类型:', typeof fileData);
        console.log('读取到的文件数据长度:', fileData.length);
        
        // 转换为ArrayBuffer
        const arrayBuffer = await this.toArrayBuffer(fileData);
        console.log('转换后的ArrayBuffer长度:', arrayBuffer.byteLength);
        
        // 发送开始帧
        this.sendStartFrame();
        
        // 使用与demo一致的分片大小，优化流式体验
        const chunkSize = 1280; // demo使用的分片大小
        const totalChunks = Math.ceil(arrayBuffer.byteLength / chunkSize);
        const startTime = Date.now();
        
        console.log(`准备发送音频数据: 总大小=${arrayBuffer.byteLength}字节, 总帧数=${totalChunks}, 每帧大小=${chunkSize}字节`);
        
        // 添加进度指示
        this.statusText = '正在进行实时语音识别...';
        
        // 使用更可靠的异步方式发送数据帧
        let sentChunks = 0;
        const sendChunk = async () => {
          if (sentChunks >= totalChunks) {
            // 所有帧发送完毕
            console.log('音频数据发送完成');
            
            // 确保发送结束帧
            if (this.isConnected && this.webSocketTask) {
              this.sendEndFrame();
            }
            
            this.statusText = '等待最终识别结果...';
            return;
          }
          
          // 检查WebSocket连接状态
          if (!this.isConnected || !this.webSocketTask) {
            console.error('WebSocket连接中断，停止发送音频数据');
            throw new Error('WebSocket连接中断');
          }
          
          // 检查是否超过1分钟限制
          if (Date.now() - startTime > 60000) {
            console.warn('语音时长已达1分钟上限');
            this.statusText = '语音时长已达1分钟上限';
            return;
          }
          
          const start = sentChunks * chunkSize;
          const end = Math.min(start + chunkSize, arrayBuffer.byteLength);
          const chunk = arrayBuffer.slice(start, end);
          
          // 判断是否为最后一帧
          const isLastFrame = end >= arrayBuffer.byteLength;
          
          console.log(`准备发送帧 ${sentChunks + 1}/${totalChunks}，数据范围: ${start}-${end}，大小: ${chunk.byteLength}字节，是否最后一帧: ${isLastFrame}`);
          
          // 发送音频数据帧
          await this.sendAudioFrame(chunk, isLastFrame);
          
          sentChunks++;
          
          // 动态调整发送速率，模拟实时录音速度
          await new Promise(resolve => setTimeout(resolve, 40)); // 40ms约等于1280字节在16kHz采样率下的时长
          
          // 继续发送下一帧
          await sendChunk();
        };
        
        // 开始发送数据帧
        await sendChunk();
      } catch (error) {
        console.error('发送音频数据失败', error);
        this.statusText = '识别过程异常';
        
        // 在微信小程序中提供更详细的错误提示
        let errorMsg = '发送失败: ' + error.message;
        if (error.message.includes('WebSocket')) {
          errorMsg = '网络连接异常，请检查网络';
        } else if (error.message.includes('readFile')) {
          errorMsg = '读取录音文件失败';
        }
        
        uni.showToast({
          title: errorMsg,
          icon: 'none'
        });
        
        this.closeWebSocket();
        throw error;
      }
    },
    
    // 读取文件 - 微信小程序兼容版本
    readFile(filePath) {
      return new Promise((resolve, reject) => {
        try {
          const fs = uni.getFileSystemManager();
          console.log('使用文件系统管理器读取文件:', filePath);
          fs.readFile({
            filePath: filePath,
            success: (res) => {
              console.log('文件读取成功，数据类型:', typeof res.data);
              console.log('文件读取成功，数据长度:', res.data.length);
              resolve(res.data);
            },
            fail: (err) => {
              console.error('读取录音文件失败', err);
              // 在微信小程序中，可能需要特殊处理不同的错误码
              let errorMsg = '读取录音文件失败: ' + err.errMsg;
              if (err.errCode === 10004) {
                errorMsg = '文件不存在或无访问权限';
              } else if (err.errCode === 10005) {
                errorMsg = '文件路径无效';
              }
              reject(new Error(errorMsg));
            }
          });
        } catch (error) {
          console.error('获取文件系统管理器失败:', error);
          reject(new Error('获取文件系统管理器失败'));
        }
      });
    },
    
    // 转换为ArrayBuffer - 微信小程序优化版本
    toArrayBuffer(buffer) {
      return new Promise((resolve, reject) => {
        try {
          // 在微信小程序中，需要特别处理不同类型的buffer
          if (typeof buffer === 'string') {
            // 如果是字符串类型，先转换为ArrayBuffer
            const arrayBuffer = new ArrayBuffer(buffer.length);
            const view = new Uint8Array(arrayBuffer);
            for (let i = 0; i < buffer.length; i++) {
              view[i] = buffer.charCodeAt(i) & 0xff;
            }
            resolve(arrayBuffer);
          } else if (buffer instanceof ArrayBuffer) {
            // 已经是ArrayBuffer，直接返回
            resolve(buffer);
          } else {
            // 其他类型，尝试转换
            const arrayBuffer = new ArrayBuffer(buffer.length);
            const view = new Uint8Array(arrayBuffer);
            for (let i = 0; i < buffer.length; i++) {
              view[i] = buffer[i];
            }
            resolve(arrayBuffer);
          }
        } catch (error) {
          console.error('转换为ArrayBuffer失败:', error);
          reject(new Error('转换音频数据失败'));
        }
      });
    },
    
    // 发送开始帧 - 微信小程序增强版本，完全符合讯飞API文档
    sendStartFrame() {
      try {
        // 确保webSocketTask存在且连接状态正常
        if (!this.webSocketTask || !this.isConnected) {
          console.warn('WebSocket未连接，跳过发送开始帧');
          return;
        }
        
        // 构建开始帧数据 - 严格按照讯飞API文档要求
        const startFrame = {
          common: {
            app_id: this.appId
          },
          business: {
            language: 'zh_cn',
            domain: 'iat',
            accent: 'mandarin',
            dwa: 'wpgs', // 动态修正开关，开启后可以获取动态修正后的文本
            vad_eos: 5000, // 语音结束检测超时时间
            vad_bos: 60000, // 语音开始检测超时时间
            ptt: 0, // 非实时转写开关，0表示实时
            rse: 1, // 结果返回编码格式，1表示返回识别结果json串
            ent: 'iat' // 引擎类型
          },
          data: {
            status: 0, // 0表示第一帧
            format: 'audio/L16;rate=16000', // 与录音参数保持一致
            encoding: 'raw',
            audio: '' // 第一帧不包含音频数据
          }
        };
        
        console.log('准备发送开始帧:', JSON.stringify(startFrame));
        
        this.webSocketTask.send({
          data: JSON.stringify(startFrame),
          success: () => {
            console.log('开始帧发送成功');
            // 发送成功后更新状态
            this.statusText = '开始语音识别...';
          },
          fail: (err) => {
            console.error('开始帧发送失败', err);
            // 在微信小程序中，提供更详细的错误码处理
            let errorMsg = '发送开始帧失败';
            if (err.errCode === 10001) {
              errorMsg = 'WebSocket连接已关闭';
            } else if (err.errCode === 10002) {
              errorMsg = '发送数据大小超过限制';
            } else if (err.errCode === 10003) {
              errorMsg = '发送数据格式错误';
            }
            
            // 显示错误提示
            uni.showToast({
              title: errorMsg,
              icon: 'none'
            });
          }
        });
      } catch (error) {
        console.error('发送开始帧异常', error);
        // 显示错误提示
        uni.showToast({
          title: '发送开始帧异常',
          icon: 'none'
        });
      }
    },
    
    // 发送音频数据帧 - 微信小程序增强版本
    async sendAudioFrame(audioData, isLastFrame = false) {
      return new Promise((resolve, reject) => {
        try {
          if (!this.webSocketTask) {
            console.error('WebSocket任务不存在');
            reject(new Error('WebSocket任务不存在'));
            return;
          }
          
          // 微信小程序兼容性增强：检查audioData类型
          console.log('音频数据类型:', Object.prototype.toString.call(audioData));
          console.log('音频数据长度:', audioData.byteLength || audioData.length);
          
          // 确保audioData是ArrayBuffer类型
          let processedAudioData = audioData;
          if (!(audioData instanceof ArrayBuffer)) {
            console.warn('音频数据不是ArrayBuffer类型，尝试转换');
            try {
              const ab = new ArrayBuffer(audioData.length);
              const view = new Uint8Array(ab);
              for (let i = 0; i < audioData.length; i++) {
                view[i] = audioData[i] & 0xff;
              }
              processedAudioData = ab;
              console.log('转换后音频数据长度:', processedAudioData.byteLength);
            } catch (conversionError) {
              console.error('转换音频数据失败:', conversionError);
              reject(new Error('转换音频数据失败'));
              return;
            }
          }
          
          // 将ArrayBuffer转换为Base64编码 - 微信小程序兼容版本
          const base64Audio = this.arrayBufferToBase64(processedAudioData);
          console.log(`音频帧Base64长度: ${base64Audio.length}, 是否最后一帧: ${isLastFrame}`);
          
          // 检查Base64编码结果是否合理
          if (!base64Audio || base64Audio.length === 0) {
            console.warn('Base64编码结果为空，可能是音频数据问题');
          } else if (base64Audio.length < 100 && !isLastFrame) {
            console.warn('音频帧Base64编码异常小，可能影响识别效果');
          }
          
          // 构建音频帧数据 - 严格按照讯飞API要求的格式
          const audioFrame = {
            data: {
              status: isLastFrame ? 2 : 1,
              format: 'audio/L16;rate=16000',
              encoding: 'raw',
              audio: base64Audio
            }
          };
          
          // 序列化帧数据
          let frameData;
          try {
            frameData = JSON.stringify(audioFrame);
            console.log(`准备发送音频帧，数据大小: ${frameData.length}字节`);
          } catch (jsonError) {
            console.error('序列化音频帧失败:', jsonError);
            reject(new Error('序列化音频帧失败'));
            return;
          }
          
          // 微信小程序中发送WebSocket消息
          this.webSocketTask.send({
            data: frameData,
            success: () => {
              console.log(`音频数据帧发送成功，帧大小: ${processedAudioData.byteLength}字节，是否最后一帧: ${isLastFrame}`);
              resolve();
            },
            fail: (err) => {
              console.error('音频数据帧发送失败', err);
              // 在微信小程序中，提供更详细的错误码处理
              let errorMsg = '发送音频帧失败';
              if (err.errCode === 10001) {
                errorMsg = 'WebSocket连接已关闭';
              } else if (err.errCode === 10002) {
                errorMsg = '发送数据大小超过限制';
              } else if (err.errCode === 10003) {
                errorMsg = '发送数据格式错误';
              } else if (err.errCode === 10004) {
                errorMsg = '服务器拒绝接收数据';
              }
              
              // 显示错误提示
              uni.showToast({
                title: errorMsg,
                icon: 'none'
              });
              reject(new Error(errorMsg));
            }
          });
          
          // 如果是最后一帧，更新状态
          if (isLastFrame) {
            this.statusText = '正在等待识别结果...';
          }
        } catch (error) {
          console.error('发送音频数据帧异常', error);
          reject(error);
        }
      });
    },
    
    // 发送结束帧 - 微信小程序增强版本
    sendEndFrame() {
      try {
        // 确保webSocketTask存在且连接状态正常
        if (!this.webSocketTask || !this.isConnected) {
          console.warn('WebSocket未连接，跳过发送结束帧');
          return;
        }
        
        const endFrame = {
          data: {
            status: 2,
            format: 'audio/L16;rate=16000',
            encoding: 'raw',
            audio: ''
          }
        };
        
        console.log('准备发送结束帧:', JSON.stringify(endFrame));
        
        this.webSocketTask.send({
          data: JSON.stringify(endFrame),
          success: () => {
            console.log('结束帧发送成功');
          },
          fail: (err) => {
            console.error('结束帧发送失败', err);
            // 结束帧失败通常不影响整体流程，可以继续处理
          }
        });
      } catch (error) {
        console.error('发送结束帧异常', error);
      }
    },
    
    // ArrayBuffer转换为Base64 - 微信小程序兼容版本
    arrayBufferToBase64(buffer) {
      try {
        // 优先使用微信小程序原生API
        if (typeof wx !== 'undefined' && wx.arrayBufferToBase64 && buffer instanceof ArrayBuffer) {
          console.log('使用微信小程序原生API进行ArrayBuffer转Base64');
          return wx.arrayBufferToBase64(buffer);
        }
        
        // 标准实现
        let binary = '';
        const bytes = new Uint8Array(buffer);
        const len = bytes.byteLength;
        
        // 避免循环过久导致性能问题
        if (len > 1000000) {
          console.warn('处理大文件，可能影响性能');
        }
        
        for (let i = 0; i < len; i++) {
          binary += String.fromCharCode(bytes[i]);
        }
        
        // 检查是否支持btoa方法
        if (typeof btoa !== 'function') {
          console.warn('当前环境不支持btoa方法，使用polyfill');
          // 提供一个简单的btoa polyfill
          return this.base64Encode(binary);
        }
        
        return btoa(binary);
      } catch (error) {
        console.error('ArrayBuffer转换为Base64失败:', error);
        // 在转换失败时，返回空字符串而不是抛出异常
        return '';
      }
    },
    
    // Base64编码的polyfill实现，用于不支持btoa的环境
    base64Encode(str) {
      const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
      let output = '';
      let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
      let i = 0;
      
      str = this.utf8Encode(str);
      
      while (i < str.length) {
        chr1 = str.charCodeAt(i++);
        chr2 = str.charCodeAt(i++);
        chr3 = str.charCodeAt(i++);
        
        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;
        
        if (isNaN(chr2)) {
          enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
          enc4 = 64;
        }
        
        output = output + 
          chars.charAt(enc1) + chars.charAt(enc2) + 
          chars.charAt(enc3) + chars.charAt(enc4);
      }
      
      return output;
    },
    
    // UTF-8编码实现，用于base64Encode的辅助函数
    utf8Encode(str) {
      str = str.replace(/\r\n/g, '\n');
      let utftext = '';
      
      for (let n = 0; n < str.length; n++) {
        const c = str.charCodeAt(n);
        
        if (c < 128) {
          utftext += String.fromCharCode(c);
        } else if ((c > 127) && (c < 2048)) {
          utftext += String.fromCharCode((c >> 6) | 192);
          utftext += String.fromCharCode((c & 63) | 128);
        } else {
          utftext += String.fromCharCode((c >> 12) | 224);
          utftext += String.fromCharCode(((c >> 6) & 63) | 128);
          utftext += String.fromCharCode((c & 63) | 128);
        }
      }
      
      return utftext;
    },
    
    // 处理WebSocket消息 - 微信小程序增强兼容性版本
    handleWebSocketMessage(data) {
      try {
        console.log('接收到WebSocket消息，长度:', data ? (data.length || '未知') : 'undefined');
        console.log('接收到WebSocket消息，类型:', Object.prototype.toString.call(data));
        
        // 微信小程序中，data可能是ArrayBuffer，需要转换为字符串
        let messageStr = data;
        if (data instanceof ArrayBuffer) {
          console.log('接收到的是ArrayBuffer类型消息，大小:', data.byteLength);
          messageStr = this.arrayBufferToString(data);
          console.log('转换后的字符串长度:', messageStr ? messageStr.length : 0);
          if (messageStr && messageStr.length > 0) {
            console.log('转换后字符串前200字符:', messageStr.substring(0, Math.min(200, messageStr.length)));
          }
        } else if (typeof data === 'object' && data.data && data.data instanceof ArrayBuffer) {
          // 处理某些平台特殊封装的ArrayBuffer数据
          console.log('检测到封装的ArrayBuffer数据');
          messageStr = this.arrayBufferToString(data.data);
          console.log('转换封装数据后的字符串长度:', messageStr ? messageStr.length : 0);
        } else if (typeof data === 'string') {
          console.log('接收到的是字符串类型消息');
        } else {
          console.log('接收到未知类型消息:', typeof data);
          console.log('尝试直接转换为字符串:', String(data));
          messageStr = String(data);
        }
        
        // 如果转换后的消息为空或无效，给出提示并返回
        if (!messageStr || typeof messageStr !== 'string' || messageStr.trim().length === 0) {
          console.warn('接收到的WebSocket消息为空或无效');
          return;
        }
        
        // 尝试清理可能的非法字符
        messageStr = messageStr.replace(/^\uFEFF/, ''); // 去除BOM头
        messageStr = messageStr.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, ''); // 替换控制字符
        
        // 解析接收到的消息
        let message;
        try {
          message = JSON.parse(messageStr);
          console.log('完整的WebSocket消息:', JSON.stringify(message).substring(0, 500));
        } catch (parseError) {
          console.error('JSON解析错误:', parseError);
          console.error('尝试解析的字符串前200字符:', messageStr.substring(0, Math.min(200, messageStr.length)));
          console.error('尝试解析的字符串后200字符:', messageStr.substring(Math.max(0, messageStr.length - 200)));
          // 尝试处理不完整的JSON或分帧消息
          this.handleFrameError(messageStr);
          return;
        }
        
        // 根据消息类型进行处理
        if (message.code === 0) {
          // 识别成功
          if (message.data && message.data.result) {
            const result = message.data.result;
            let recognizedText = '';
            
            // 增强兼容性：尝试多种格式提取识别文本 - 更全面的支持
            console.log('尝试提取识别结果，result对象结构:', Object.keys(result).join(', '));
            
            // 1. 尝试标准格式 (ws结构) - 讯飞官方推荐格式
            if (result.ws && Array.isArray(result.ws)) {
              console.log('检测到ws结构，长度:', result.ws.length);
              for (let i = 0; i < result.ws.length; i++) {
                if (result.ws[i].cw && Array.isArray(result.ws[i].cw) && result.ws[i].cw.length > 0) {
                  recognizedText = recognizedText + result.ws[i].cw[0].w;
                  console.log(`提取到文本片段: ${result.ws[i].cw[0].w}`);
                }
              }
              console.log('通过ws结构提取的文本:', recognizedText);
            }
            
            // 2. 尝试直接获取text字段
            if (!recognizedText && result.text) {
              recognizedText = result.text;
              console.log('通过text字段提取的文本:', recognizedText);
            }
            
            // 3. 尝试其他可能的字段结构 - 微信小程序特有的格式支持
            if (!recognizedText) {
              // 检查是否是JSON字符串形式的result
              if (typeof result === 'string' && result.includes('{')) {
                try {
                  const nestedResult = JSON.parse(result);
                  console.log('检测到嵌套JSON结果，尝试提取...');
                  if (nestedResult.ws) {
                    // 递归调用以处理嵌套结构
                    const nestedMessage = {code: 0, data: {result: nestedResult}};
                    this.handleWebSocketMessage(JSON.stringify(nestedMessage));
                    return;
                  }
                } catch (e) {
                  console.warn('解析嵌套JSON失败:', e);
                }
              }
              
              // 检查更多可能包含文本的字段
              const possibleFields = [
                'message.data.text',
                'message.text',
                'result.st',
                'result.recognition',
                'result.content',
                'message.result',
                'message.content'
              ];
              
              for (const field of possibleFields) {
                try {
                  const value = eval(`(function(){try{return ${field};}catch(e){return null;}})()`);
                  if (value && typeof value === 'string' && value.trim()) {
                    recognizedText = value;
                    console.log(`通过${field}字段提取的文本:`, recognizedText);
                    break;
                  }
                } catch (e) {
                  // 忽略字段访问错误
                }
              }
            }
            
            // 4. 如果以上方法都失败，尝试正则表达式提取可能的文本
            if (!recognizedText && messageStr) {
              try {
                const textMatches = messageStr.match(/"([^"]{2,})"/g);
                if (textMatches && textMatches.length > 0) {
                  // 过滤掉太短的字符串和可能的JSON键名
                  const filteredMatches = textMatches.filter(match => {
                    const text = match.slice(1, -1); // 去除引号
                    return text.length > 2 && !text.includes(':') && !['code', 'data', 'result', 'status', 'message'].includes(text);
                  });
                  if (filteredMatches.length > 0) {
                    recognizedText = filteredMatches.map(match => match.slice(1, -1)).join('');
                    console.log('通过正则表达式提取的文本:', recognizedText);
                  }
                }
              } catch (e) {
                console.warn('正则提取文本失败:', e);
              }
            }
            
            // 处理动态修正功能 - 增强版本
            if (result.pgs) {
              console.log('检测到pgs标志:', result.pgs);
              if (result.pgs === 'apd') {
                // 将临时结果同步给最终结果
                this.recognitionResult = this.recognitionResultTemp || "";
                console.log('同步临时结果到最终结果:', this.recognitionResult);
              }
              // 将结果存储在临时变量中
              if (recognizedText && recognizedText.trim()) {
                this.recognitionResultTemp = (this.recognitionResult || "") + recognizedText;
                this.recognitionResult = this.recognitionResultTemp;
              }
            } else {
              // 普通结果处理，确保结果不为空字符串
              if (recognizedText && recognizedText.trim()) {
                this.recognitionResult = (this.recognitionResult || "") + recognizedText;
              }
            }
            
            // 记录当前结果状态
            console.log('当前识别结果:', this.recognitionResult);
            
            this.statusText = '实时识别中...';
            // 添加识别动画效果
            this.$emit('recognition-update');
            
            // 检查是否识别结束
            if (message.data.status === 2) {
              this.statusText = '识别完成';
              console.log('最终识别结果:', this.recognitionResult);
              
              // 如果识别结果为空，给出提示并尝试从messageStr中直接提取
              if (!this.recognitionResult.trim()) {
                console.warn('识别结果为空，尝试从原始消息中直接提取');
                // 尝试直接从messageStr中提取文本
                const extractedText = this.extractTextFromRawMessage(messageStr);
                if (extractedText && extractedText.trim()) {
                  this.recognitionResult = extractedText;
                  console.log('从原始消息中提取到文本:', this.recognitionResult);
                  uni.showToast({
                    title: '识别成功',
                    icon: 'success'
                  });
                } else {
                  uni.showToast({
                    title: '识别结果为空，请重试',
                    icon: 'none'
                  });
                }
              } else {
                uni.showToast({
                  title: '识别成功',
                  icon: 'success'
                });
              }
              
              // 关闭WebSocket连接
              setTimeout(() => {
                this.closeWebSocket();
              }, 1000);
            }
          } else {
            console.warn('收到成功消息但无结果数据:', JSON.stringify(message).substring(0, 300));
            // 在微信小程序中，可能需要特别处理某些成功但无数据的情况
            if (message.data && message.data.status === 2) {
              console.log('检测到结束标志，但无识别结果');
              this.statusText = '识别完成';
              
              // 尝试从原始消息中提取文本
              if (!this.recognitionResult.trim() && messageStr) {
                const extractedText = this.extractTextFromRawMessage(messageStr);
                if (extractedText && extractedText.trim()) {
                  this.recognitionResult = extractedText;
                  console.log('从原始消息中提取到文本:', this.recognitionResult);
                  uni.showToast({
                    title: '识别成功',
                    icon: 'success'
                  });
                } else {
                  uni.showToast({
                    title: '识别结果为空，请重试',
                    icon: 'none'
                  });
                }
              }
              
              // 关闭WebSocket连接
              setTimeout(() => {
                this.closeWebSocket();
              }, 1000);
            }
          }
        } else {
          // 识别失败
          console.error('语音识别失败', message);
          this.statusText = '识别失败';
          uni.showToast({
            title: '识别失败: ' + (message.message || '未知错误'),
            icon: 'none',
            duration: 3000
          });
          // 关闭WebSocket连接
          this.closeWebSocket();
        }
      } catch (error) {
        console.error('处理WebSocket消息失败', error);
        console.error('原始数据类型:', typeof data);
        console.error('原始数据长度:', data ? (data.length || '未知') : 'undefined');
        // 处理JSON解析错误
        if (error instanceof SyntaxError) {
          console.warn('JSON解析错误，可能是分帧问题或数据格式不匹配');
          // 尝试处理分帧消息
          this.handleFrameError(data);
        } else {
          // 其他错误，显示更友好的提示
          this.statusText = '处理识别结果异常';
          uni.showToast({
            title: '处理识别结果异常',
            icon: 'none'
          });
        }
      }
    },
    
    // 从原始消息中提取文本 - 作为最后的备用方案
    extractTextFromRawMessage(messageStr) {
      try {
        console.log('尝试从原始消息中提取文本');
        
        // 方案1: 尝试提取所有中文字符
        const chineseChars = messageStr.match(/[\u4e00-\u9fa5]+/g);
        if (chineseChars && chineseChars.length > 0) {
          const extracted = chineseChars.join('');
          console.log('提取到中文字符:', extracted);
          return extracted;
        }
        
        // 方案2: 尝试提取所有连续的非特殊字符
        const textBlocks = messageStr.match(/[a-zA-Z0-9\u4e00-\u9fa5，。？！；：,.?!;:\s]+/g);
        if (textBlocks && textBlocks.length > 0) {
          // 选择最长的文本块
          textBlocks.sort((a, b) => b.length - a.length);
          const extracted = textBlocks[0].trim();
          console.log('提取到文本块:', extracted);
          return extracted;
        }
        
        console.warn('无法从原始消息中提取有效文本');
        return '';
      } catch (error) {
        console.error('提取文本失败:', error);
        return '';
      }
    },
    
    // ArrayBuffer转换为字符串 - 适配微信小程序环境
    arrayBufferToString(buffer) {
      try {
        // 首先检查buffer是否有效
        if (!buffer || !(buffer instanceof ArrayBuffer) || buffer.byteLength === 0) {
          console.warn('无效的ArrayBuffer数据');
          return '';
        }
        
        console.log('准备转换ArrayBuffer为字符串，长度:', buffer.byteLength);
        
        // 微信小程序兼容模式 - 优化版本
        if (typeof wx !== 'undefined' && wx.arrayBufferToBase64) {
          console.log('使用微信小程序原生API: arrayBufferToBase64');
          try {
            const base64 = wx.arrayBufferToBase64(buffer);
            console.log('base64转换结果长度:', base64.length);
            
            // 避免使用可能不可用的window.atob，改用自定义的base64解码方法
            const decodedStr = this.base64DecodeToUtf8(base64);
            console.log('base64解码后字符串长度:', decodedStr.length);
            return decodedStr;
          } catch (e) {
            console.warn('微信小程序原生API处理失败，使用备用方案:', e);
          }
        }
        
        // 主要方案：直接逐字节转换，这是最可靠的方法
        console.log('使用逐字节转换方案');
        const uint8Array = new Uint8Array(buffer);
        let result = '';
        
        // 处理大型数据时避免性能问题
        if (uint8Array.length > 10000) {
          console.log('处理大型ArrayBuffer数据，长度:', uint8Array.length);
          // 分块处理大型数据
          const chunkSize = 8192;
          for (let i = 0; i < uint8Array.length; i += chunkSize) {
            const chunk = uint8Array.subarray(i, Math.min(i + chunkSize, uint8Array.length));
            for (let j = 0; j < chunk.length; j++) {
              result += String.fromCharCode(chunk[j]);
            }
          }
        } else {
          // 普通数据直接处理
          for (let i = 0; i < uint8Array.length; i++) {
            result += String.fromCharCode(uint8Array[i]);
          }
        }
        
        console.log('ArrayBuffer转换为字符串成功，结果长度:', result.length);
        return result;
      } catch (error) {
        console.error('ArrayBuffer转换为字符串失败:', error);
        // 终极备用方案：返回空字符串以避免程序崩溃
        return '';
      }
    },
    
    // Base64解码为UTF-8字符串 - 微信小程序兼容版
    base64DecodeToUtf8(base64) {
      const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
      let str = '';
      let bytes = [];
      let i = 0;
      
      // 去除base64中的非有效字符
      base64 = base64.replace(/[^A-Za-z0-9+/=]/g, '');
      
      while (i < base64.length) {
        const enc1 = chars.indexOf(base64.charAt(i++));
        const enc2 = chars.indexOf(base64.charAt(i++));
        const enc3 = chars.indexOf(base64.charAt(i++));
        const enc4 = chars.indexOf(base64.charAt(i++));
        
        const chr1 = (enc1 << 2) | (enc2 >> 4);
        const chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
        const chr3 = ((enc3 & 3) << 6) | enc4;
        
        bytes.push(chr1);
        
        if (enc3 !== 64) {
          bytes.push(chr2);
        }
        
        if (enc4 !== 64) {
          bytes.push(chr3);
        }
      }
      
      // 将字节数组转换为UTF-8字符串
      let result = '';
      for (let j = 0; j < bytes.length; j++) {
        result += String.fromCharCode(bytes[j]);
      }
      
      return result;
    },
    
    // 处理分帧错误，尝试重新组合消息 - 增强实现
    handleFrameError(rawData) {
      try {
        console.log('尝试处理可能的分帧消息');
        
        // 如果rawData是ArrayBuffer，先转换为字符串
        let messageStr = rawData;
        if (rawData instanceof ArrayBuffer) {
          messageStr = this.arrayBufferToString(rawData);
        } else if (typeof rawData === 'object' && rawData.data && rawData.data instanceof ArrayBuffer) {
          messageStr = this.arrayBufferToString(rawData.data);
        }
        
        // 检查是否是字符串
        if (typeof messageStr !== 'string') {
          messageStr = String(messageStr);
        }
        
        console.log('分帧消息长度:', messageStr.length);
        console.log('分帧消息前200字符:', messageStr.substring(0, 200));
        
        // 尝试处理可能的部分JSON或合并的JSON
        // 1. 清理可能的BOM头和控制字符
        messageStr = messageStr.replace(/^\uFEFF/, '');
        messageStr = messageStr.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, '');
        
        // 2. 尝试查找JSON对象的边界
        const jsonStart = messageStr.indexOf('{');
        const jsonEnd = messageStr.lastIndexOf('}');
        
        if (jsonStart !== -1 && jsonEnd !== -1 && jsonEnd > jsonStart) {
          const possibleJson = messageStr.substring(jsonStart, jsonEnd + 1);
          console.log('尝试提取可能的JSON:', possibleJson.substring(0, 200));
          
          try {
            const parsed = JSON.parse(possibleJson);
            console.log('成功解析部分JSON');
            // 手动调用handleWebSocketMessage处理解析出的JSON
            this.handleWebSocketMessage(parsed);
            return;
          } catch (e) {
            console.warn('提取的JSON片段解析失败:', e);
          }
        }
        
        // 3. 检查是否是多个连续的JSON对象
        try {
          // 添加逗号并包装成数组
          const wrapped = '[' + messageStr.replace(/}\s*{/g, '},{') + ']';
          const parsed = JSON.parse(wrapped);
          console.log('成功解析为多个JSON对象数组，数量:', parsed.length);
          
          // 处理每个对象
          for (const obj of parsed) {
            this.handleWebSocketMessage(obj);
          }
          return;
        } catch (e) {
          console.warn('尝试解析为多个JSON对象失败:', e);
        }
        
        // 4. 检查是否是微信小程序特定格式的消息
        if (messageStr.includes('result') && messageStr.includes('status')) {
          console.log('检测到可能包含结果的非JSON格式消息');
          // 尝试提取关键字段
          const resultMatch = messageStr.match(/result[^\"]*"(.*?)"/);
          if (resultMatch && resultMatch[1]) {
            console.log('从非JSON格式中提取到结果:', resultMatch[1]);
            // 手动更新识别结果
            this.recognitionResult = (this.recognitionResult || '') + resultMatch[1];
            this.statusText = '实时识别中...';
            this.$emit('recognition-update');
          }
        }
        
        // 5. 如果以上方法都失败，显示错误提示
        console.error('无法处理的分帧消息，原始数据:', messageStr.substring(0, 500));
        uni.showToast({
          title: '接收到不完整的识别结果',
          icon: 'none'
        });
        
      } catch (e) {
        console.error('分帧消息处理失败', e);
      }
    },
    
    // 关闭WebSocket连接 - 添加防重入机制和优化状态管理
    closeWebSocket() {
      console.log('执行closeWebSocket方法');
      
      // 检查是否已经在关闭过程中，如果是则直接返回，避免重复关闭导致的错误
      if (this.isClosing) {
        console.log('WebSocket关闭操作已在进行中，避免重复关闭');
        return;
      }
      
      // 设置关闭标志
      this.isClosing = true;
      
      // 先更新状态标志
      const wasConnecting = this.isConnecting;
      const wasConnected = this.isConnected;
      this.isConnecting = false;
      this.isConnected = false;
      
      // 只有当webSocketTask存在时才尝试关闭操作
      if (this.webSocketTask) {
        try {
          // 检查close方法是否存在
          if (typeof this.webSocketTask.close === 'function') {
            try {
              // 尝试使用带参数的close方法
              this.webSocketTask.close({code: 1000});
              console.log('成功调用带参数的close方法');
            } catch (e) {
              try {
                // 如果带参数失败，尝试无参数调用
                this.webSocketTask.close();
                console.log('成功调用无参数的close方法');
              } catch (innerError) {
                // 如果仍然失败，检查是否可以使用abort方法
                if (this.webSocketTask.abort && typeof this.webSocketTask.abort === 'function') {
                  try {
                    this.webSocketTask.abort();
                    console.log('成功调用abort方法');
                  } catch (abortError) {
                    console.warn('尝试关闭/中止WebSocket连接失败:', abortError);
                  }
                } else {
                  console.warn('尝试关闭WebSocket连接失败:', innerError);
                }
              }
            }
          } else if (this.webSocketTask.abort && typeof this.webSocketTask.abort === 'function') {
            // 如果没有close方法但有abort方法，使用abort
            try {
              this.webSocketTask.abort();
              console.log('成功调用abort方法');
            } catch (abortError) {
              console.warn('尝试中止WebSocket连接失败:', abortError);
            }
          } else {
            console.warn('webSocketTask存在但没有close或abort方法');
          }
        } catch (error) {
          // 捕获所有可能的异常，确保程序不会崩溃
          console.warn('关闭WebSocket连接时发生异常:', error);
        }
        
        // 延迟设置为null，给底层一点时间处理关闭事件，防止'closeSocket:fail task not found'
        setTimeout(() => {
          if (this.webSocketTask) {
            console.log('清理webSocketTask引用');
            this.webSocketTask = null;
          }
        }, 200); // 稍微延长延迟时间，确保底层有足够时间处理
      } else {
        console.log('webSocketTask不存在，无需关闭');
      }
      
      // 根据之前的状态设置适当的状态文本
        if (wasConnecting) {
          this.statusText = 'WebSocket连接建立被取消';
        } else if (wasConnected) {
          this.statusText = 'WebSocket连接已关闭';
        } else {
          this.statusText = 'WebSocket连接未建立';
        }
       
       // 确保在方法结束时重置isClosing标志
       setTimeout(() => {
         this.isClosing = false;
         console.log('WebSocket关闭标志已重置，isClosing = false');
       }, 300); // 稍微延迟重置，确保关闭过程完全结束
       
       console.log('closeWebSocket方法执行完毕，当前状态:', this.statusText);
    },
    
    // 清除识别结果
    clearResult() {
      this.recognitionResult = '';
    },
    
    // 触摸开始录音（用于模板中@touchstart事件）
    startVoiceRecording() {
      this.startRecording();
    },
    
    // 触摸结束录音（用于模板中@touchend和@touchcancel事件）
    stopVoiceRecording() {
      this.stopRecording();
    },
    
    // 复制识别结果到剪贴板
    async copyResult() {
      if (!this.recognitionResult.trim()) {
        uni.showToast({
          title: '没有可复制的内容',
          icon: 'none'
        });
        return;
      }
      
      try {
        await uni.setClipboardData({
          data: this.recognitionResult
        });
        uni.showToast({
          title: '复制成功',
          icon: 'success'
        });
      } catch (error) {
        console.error('复制失败:', error);
        uni.showToast({
          title: '复制失败，请重试',
          icon: 'none'
        });
      }
    }
  }
};